/* 
 * File:   Thread.cpp
 * Author: mm021791
 * 
 * Created on 17 de octubre de 2012, 14:41
 */


#include "common_Thread.h"

#define THREAD_CANCELADO 0

using namespace TP::Threading;

Thread::Thread(){
    this->trabajando = false;
}

Thread::~Thread(){}

void Thread::Iniciar() throw (Excepcion&){
    try
    {
        switch (pthread_create( &this->thread, NULL, &correr_helper, this))
        {
            case EAGAIN: 
                throw Excepcion ("Insufficient resources to create another thread, or a system-imposed limit on the number of threads was encountered.  The latter case may occur in two ways: the RLIMIT_NPROC soft resource limit (set via setrlimit(2)), which limits the number of process for a real user ID, was reached; or the kernel's system-wide limit on the number ofthreads, /proc/sys/kernel/threads-max, was reached.");

            case EINVAL: 
                throw Excepcion ("Invalid settings in attr.");

            case EPERM:  
                throw Excepcion ("No permission to set the scheduling policy and parameters specified in attr.");
        }
    }
    catch (Excepcion& pEx)      
    {
        pEx.expandirMensaje("Fallo al iniciar el thread.");
        throw pEx;
    }
}

void Thread::Finalizar() throw (Excepcion&){
    
    try
    {
        switch (pthread_join (this->thread, NULL))
        {
            case EDEADLK:
                throw Excepcion ("A deadlock was detected (e.g., two threads tried to join with each other); or thread specifies the calling thread.");

            case EINVAL:
                throw Excepcion ("thread is not a joinable thread or Another thread is already waiting to join with this thread.");
                
            case ESRCH:
                throw Excepcion ("No thread with the ID thread could be found.");
        }
    }
    catch (Excepcion& pEx)
    {
        pEx.expandirMensaje("Fallo al finalizar el thread.");
        throw;
    }
}

bool Thread::Trabajando(){
    return this->trabajando;
}

int Thread::ID (){
    return (int) this->thread;
}

void* Thread::correr (void* pArgs){
    this->trabajando = true;
    this->tarea();
    this->trabajando = false;
    return NULL;
}

